123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- "use client";
- import Sidebar from "@/components/Layout/Sidebar";
- import { useSystemStore } from "@/stores/useSystemStore";
- import { ConfigProvider, Mask } from "antd-mobile";
- import ptBR from "antd-mobile/es/locales/pt-BR";
- import { ThemeProviderProps } from "next-themes/dist/types";
- import { ReactNode, useEffect, useMemo, useState } from "react";
- import { server } from "@/utils/client";
- import { useDebounceEffect, useRequest } from "ahooks";
- import clsx from "clsx";
- import { initializeApp } from "firebase/app";
- import { getMessaging, getToken, onMessage } from "firebase/messaging";
- import { usePathname, useSearchParams } from "next/navigation";
- import Script from "next/script";
- import { setupFontSize } from "@/utils";
- import { Local } from "@/utils/storage";
- import { motion } from "framer-motion";
- import Image from "next/image";
- import styles from "./style.module.scss";
- export interface ProvidersProps {
- children: ReactNode;
- themeProps?: Omit<ThemeProviderProps, "children">;
- }
- // 初始化 fireBase
- const initFirebase = () => {
- // 是否是https
- if (document.location.protocol.indexOf("https") === -1) return;
- // 浏览器是否支持 且是 pwa
- if (!window.Notification) {
- return;
- }
- // 是否开启通知
- // new Notification("这是标题", {
- // body: "这是正文",
- // icon: "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
- // requireInteraction: true,
- // image: "https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png",
- // });
- if (Notification.permission === "default") {
- // 征求用户的许可
- Notification.requestPermission();
- }
- if (Notification.permission === "denied") return;
- const app = initializeApp({
- apiKey: process.env.NEXT_PUBLIC_FIREBASE_APIKEY,
- authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTHDOMAIN,
- projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECTID,
- storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGEBUCKET,
- messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGINGSENDERID,
- appId: process.env.NEXT_PUBLIC_FIREBASE_APPID,
- measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENTID,
- });
- const messaging = getMessaging(app);
- // 针对单机测试,或者服务端需要使用这个key可以放开
- // if (process.env.NODE_ENV === "development") {
- getToken(messaging, {
- vapidKey: process.env.NEXT_PUBLIC_FIREBASE_KEYS,
- }).then((res) => {});
- // }
- onMessage(messaging, (payload) => {
- const notifica = new Notification(payload.data?.title || "", {
- body: payload.data?.body,
- icon: payload.data?.image,
- ...payload.data,
- });
- });
- };
- /**
- * 获取停服公告信息
- * POST /v1/api/front/suspension
- * 接口ID:263127760
- * 接口地址:https://app.apifox.com/link/project/4790544/apis/api-263127760
- */
- interface SuspensionType {
- able: boolean;
- }
- const getStopServiceApi = () => {
- return server
- .post<SuspensionType>({
- url: "/v1/api/front/suspension",
- data: { renter_id: "10000" },
- })
- .then((res) => {
- return res.data.able ?? false;
- });
- };
- /**
- * @description 停服通知
- */
- const StopServiceClient = () => {
- const { data: isSuspension } = useRequest(getStopServiceApi, {
- pollingInterval: 10000,
- pollingErrorRetryCount: 3,
- });
- return (
- <>
- {isSuspension && (
- <div
- className={
- "absolute left-0 right-0 top-[0.4rem] z-[99999] bg-[#fff] p-[20px]" +
- " text-[14px] text-[#000]"
- }
- >
- <div className={"flex items-center"}>
- <div>
- <motion.div
- animate={{ opacity: [0, 100, 0] }}
- transition={{ repeat: Infinity, repeatDelay: 1 }}
- >
- <span
- className={
- "iconfont icon-gantanhao mr-[10px] text-primary-color" +
- " text-[0.2rem]"
- }
- ></span>
- </motion.div>
- </div>
- <span>
- O site está prestes a parar de ser atualizado, a fim de proteger a
- segurança de seus fundos, temporariamente impossibilitado de fazer
- apostas
- </span>
- </div>
- </div>
- )}
- </>
- );
- };
- /**
- * @description 全局弹窗
- */
- const GlobalNotify = () => {
- const [visible, setVisible] = useState(false);
- return (
- <>
- <Mask visible={visible} onMaskClick={() => setVisible(false)}>
- <div className="absolute left-0 top-[22%] w-[100%]">
- <div className={"relative h-[2.6rem]"}>
- {/*内容*/}
- <div
- className={"absolute left-0 top-0 z-10 h-[100%] w-[100%] p-[0.4167rem]"}
- >
- <div className={"flex h-[100%] flex-col items-center justify-center"}>
- <p className={"text-[0.2083rem] font-semibold text-[#532e0a]"}>
- GANHE UM BÔNUS DE
- </p>
- <p
- className={
- "text-[0.5rem] font-black leading-[0.5rem]" +
- " text-[#ec5c52]"
- }
- >
- 999.00
- </p>
- </div>
- </div>
- {/*title*/}
- <Image
- src={"/notify/title.png"}
- className={
- "absolute -top-[0.7rem] left-1/2 -translate-x-1/2" +
- " w-[2.7778rem]"
- }
- alt={""}
- width={400}
- height={70}
- />
- {/*铃铛*/}
- <Image
- src={"/notify/bell.png"}
- className={
- "absolute -top-[0.1rem] left-1/2 w-[0.8333rem] -translate-x-1/2"
- }
- alt={""}
- width={120}
- height={70}
- />
- {/*金币*/}
- <Image
- src={"/notify/money.png"}
- alt={""}
- width={750}
- className={
- "absolute -top-[0.5rem] left-0 h-[3.2rem] animate-slow-bounce"
- }
- height={512}
- />
- {/*光*/}
- <Image
- src={"/notify/light.png"}
- alt={""}
- width={750}
- className={
- "absolute -top-[120px] left-0 -z-10 h-[4.2rem] animate-spin" +
- " border-[green]"
- }
- style={{ animationDuration: "4s" }}
- height={512}
- />
- <Image
- src={"/notify/light1.png"}
- alt={""}
- width={750}
- className={"absolute -top-[80px] left-0 -z-10 h-[3.2rem]"}
- height={512}
- />
- {/*背景*/}
- <Image
- src={"/notify/bg.png"}
- alt={""}
- width={750}
- height={424}
- className={"mx-auto h-[2.6rem] w-[90%]"}
- />
- </div>
- </div>
- </Mask>
- </>
- );
- };
- /**
- * @description 初始化pixel广告追踪
- *
- * 1:获取url参数
- * - 如果 有url参数获取并存入本地缓存
- * - 如果 没有url参数获取本地缓存
- * 2:根据类型获取对应的id
- */
- //bcwin?ch=ugZ8z9mf8x&type=kwai_pixel&kwaiPixel=2222 fbPixel kwaiPixel
- // bcwin11111?ch=TcC4Wno4Cq&type=facebook_pixel&fbPixel=625811426763645 // kwai 271573370973328
- /**
- * @description type
- * 1: kwai_pixel
- * 2: facebook_pixel
- */
- const InitAdvertise = () => {
- const pathname = useSearchParams();
- // pixel 类型
- const [pixelType, setPixelType] = useState<string | null>(null);
- const [pixelId, setPixelId] = useState<string | null>(null);
- // 快玩id
- const kwaiPixel = pathname.get("kwaiPixel");
- const kwaiClick_id = pathname.get("click_id");
- // facebook id
- const facebookPixel = pathname.get("fbPixel");
- // console.log(
- // `🚀🚀🚀🚀🚀-> in providers.tsx on 152`,
- // typeof window,
- // typeof window !== undefined ? window.localStorage.getItem("pixel_type") : ""
- // );
- useEffect(() => {
- if (kwaiPixel) {
- setPixelType("kwai_pixel");
- Local.setKey("ban_pixel_type", "kwai_pixel");
- Local.setKey("ban_pixel_id", kwaiPixel);
- } else if (facebookPixel) {
- setPixelType("facebook_pixel");
- Local.setKey("ban_pixel_type", "facebook_pixel");
- Local.setKey("ban_pixel_id", facebookPixel);
- } else {
- const type = Local.getKey("ban_pixel_type");
- setPixelType(type);
- }
- if (kwaiClick_id) {
- Local.setKey("ban_click_id", kwaiClick_id);
- }
- setPixelId(kwaiPixel || facebookPixel || Local.getKey("ban_pixel_id"));
- }, []);
- return (
- <>
- {pixelType === "facebook_pixel" && (
- <Script
- id={"facebook"}
- strategy={"afterInteractive"}
- dangerouslySetInnerHTML={{
- __html: `
- fbq('init', '${pixelId}');
- `,
- }}
- ></Script>
- )}
- {pixelType === "kwai_pixel" && (
- <Script
- id={"kwai"}
- strategy={"afterInteractive"}
- dangerouslySetInnerHTML={{
- __html: `
- kwaiq.load('${pixelId}');
- kwaiq.page();
- `,
- }}
- ></Script>
- )}
- </>
- );
- };
- export default function SidebarLayout({ children, themeProps }: ProvidersProps) {
- const { isCollapse, setCollapse } = useSystemStore((state) => ({
- isCollapse: state.isCollapse,
- setCollapse: state.setCollapse,
- }));
- const pathname = usePathname();
- const isShowBg = useMemo(() => {
- const local = pathname.split("/")[1];
- if (`/${local}` === pathname) return true;
- return [
- `/${local}/freeGames`,
- `/${local}/replayGames`,
- `/${local}/promo`,
- `/${local}/gameList`,
- ].includes(pathname);
- }, [pathname]);
- return (
- <div id={"app"} className="relative h-[100%] overflow-hidden">
- <motion.div
- className="fixed left-0 top-0 z-30 h-[100%] w-[70%]"
- initial={{ x: "-100%" }}
- animate={{ x: isCollapse ? 0 : "-100%" }}
- transition={{ type: "tween", duration: 0.3 }}
- >
- <Sidebar />
- </motion.div>
- {/* Main Content transform: translate(0, 0);*/}
- <motion.div
- className="relative z-10 h-[100%] translate-x-0 translate-y-0 transform"
- animate={{ x: isCollapse ? "70%" : "0%" }}
- transition={{ type: "tween", duration: 0.3 }}
- >
- <div
- className={clsx(isCollapse ? "containerMask" : "")}
- onClick={() => {
- setCollapse(false);
- }}
- ></div>
- {/*停服通知*/}
- <StopServiceClient />
- {/*充值成功通知*/}
- <GlobalNotify />
- <section className={clsx(isShowBg && styles.homePage, "relative h-[100%]")}>
- {children}
- </section>
- </motion.div>
- </div>
- );
- }
- export const Providers = ({ children, themeProps }: ProvidersProps) => {
- const setupConfig = useSystemStore((state) => state.setupConfig);
- useDebounceEffect(() => {
- if ("serviceWorker" in navigator) {
- initFirebase();
- }
- // 初始化配置
- setupConfig();
- // 初始化字体
- setupFontSize();
- }, []);
- return (
- <ConfigProvider locale={ptBR}>
- <Script
- id={"facebookScript"}
- strategy={"beforeInteractive"}
- dangerouslySetInnerHTML={{
- __html: `<!-- Meta Pixel Code -->
- !function(f,b,e,v,n,t,s)
- {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
- n.callMethod.apply(n,arguments):n.queue.push(arguments)};
- if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
- n.queue=[];t=b.createElement(e);t.async=!0;
- t.src=v;s=b.getElementsByTagName(e)[0];
- s.parentNode.insertBefore(t,s)}(window, document,'script',
- 'https://connect.facebook.net/en_US/fbevents.js');
- <!-- End Meta Pixel Code -->`,
- }}
- ></Script>
- <Script
- id={"kwaiScript"}
- strategy={"beforeInteractive"}
- dangerouslySetInnerHTML={{
- __html: `
- !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.install=t():e.install=t()}(window,(function(){return function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";var o=this&&this.__spreadArray||function(e,t,n){if(n||2===arguments.length)for(var o,r=0,i=t.length;r<i;r++)!o&&r in t||(o||(o=Array.prototype.slice.call(t,0,r)),o[r]=t[r]);return e.concat(o||Array.prototype.slice.call(t))};Object.defineProperty(t,"__esModule",{value:!0});var r=function(e,t,n){var o,i=e.createElement("script");i.type="text/javascript",i.async=!0,i.src=t,n&&(i.onerror=function(){r(e,n)});var a=e.getElementsByTagName("script")[0];null===(o=a.parentNode)||void 0===o||o.insertBefore(i,a)};!function(e,t,n){e.KwaiAnalyticsObject=n;var i=e[n]=e[n]||[];i.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"];var a=function(e,t){e[t]=function(){for(var n=[],r=0;r<arguments.length;r++)n[r]=arguments[r];var i=o([t],n,!0);e.push(i)}};i.methods.forEach((function(e){a(i,e)})),i.instance=function(e){var t,n=(null===(t=i._i)||void 0===t?void 0:t[e])||[];return i.methods.forEach((function(e){a(n,e)})),n},i.load=function(e,o){var a="https://s1.kwai.net/kos/s101/nlav11187/pixel/events.js";i._i=i._i||{},i._i[e]=[],i._i[e]._u=a,i._t=i._t||{},i._t[e]=+new Date,i._o=i._o||{},i._o[e]=o||{};var c="?sdkid=".concat(e,"&lib=").concat(n);r(t,a+c,"https://s16-11187.ap4r.com/kos/s101/nlav11187/pixel/events.js"+c)}}(window,document,"kwaiq")}])}));
- `,
- }}
- ></Script>
- <InitAdvertise />
- <SidebarLayout>{children}</SidebarLayout>
- </ConfigProvider>
- );
- };
|